package cn.sfrog.project.biz.admin.tencent;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.sfrog.common.core.domain.AjaxResult;
import cn.sfrog.common.exception.LiveException;
import cn.sfrog.common.exception.ServiceException;
import cn.sfrog.project.biz.admin.utils.tencentlive.LiveUtils;
import cn.sfrog.project.biz.web.vo.room.LiveAddressVO;
import org.apache.http.protocol.HttpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;

/**
 * @Author chenl
 * @Date 2024-05-26 08:52
 * @title TencentLiveApiService
 * @description 腾讯云直播与IM的api接口调用封装
 **/
@Service
public class TencentLiveApiService {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private TencentLiveProperties liveProperties;

    private static final String API_CreateGroup = "/v4/group_open_http_svc/create_group";//创建群组接口
    private static final String API_GetAppidGroupList = "/v4/group_open_http_svc/get_appid_group_list";//获取app中的所有群组
    private static final String API_AccountImport = "/v4/im_open_login_svc/account_import";//导入单个账号
    private static final String API_AccountCheck = "/v4/im_open_login_svc/account_check";//账号查询
    private static final String API_QueryOnlineStatus = "/v4/openim/query_online_status";//查询账号在线状态

    /**
     * 根据streamName 和txtime 获取推拉流地址
     *
     * @param streamName
     * @param txTime
     * @return
     */
    public LiveAddressVO getPushAndPullStreamUrl(String streamName, LocalDateTime txTime) {

        long txTime1 = LiveUtils.getTxTime(txTime);

        String pushRtmpUrl = new StringBuilder()
                .append("rtmp://")
                .append(liveProperties.getPushDomain())
                .append(liveProperties.getAppName())
                .append(streamName)
                .append("?")
                .append(LiveUtils.getSafeUrl(liveProperties.getPushKey(), streamName, txTime1))
                .toString();

        String pullRtmpUrl = new StringBuilder()
                .append("rtmp://")
                .append(liveProperties.getPullDomain())
                .append(liveProperties.getAppName())
                .append(streamName)
                .append("?")
                .append(LiveUtils.getSafeUrl(liveProperties.getPullKey(), streamName, txTime1))
                .toString();

        String pullFlvUrl = new StringBuilder()
                .append("http://")
                .append(liveProperties.getPullDomain())
                .append(liveProperties.getAppName())
                .append(streamName)
                .append(".flv?")
                .append(LiveUtils.getSafeUrl(liveProperties.getPullKey(), streamName, txTime1))
                .toString();

        String pullHlsUrl = new StringBuilder()
                .append("http://")
                .append(liveProperties.getPullDomain())
                .append(liveProperties.getAppName())
                .append(streamName)
                .append(".m3u8?")
                .append(LiveUtils.getSafeUrl(liveProperties.getPullKey(), streamName, txTime1))
                .toString();

        String pullWebrtcUrl = new StringBuilder()
                .append("webrtc://")
                .append(liveProperties.getPullDomain())
                .append(liveProperties.getAppName())
                .append(streamName)
                .append("?")
                .append(LiveUtils.getSafeUrl(liveProperties.getPullKey(), streamName, txTime1))
                .toString();

        String pushWebrtcUrl = new StringBuilder()
                .append("webrtc://")
                .append(liveProperties.getPushDomain())
                .append(liveProperties.getAppName())
                .append(streamName)
                .append("?")
                .append(LiveUtils.getSafeUrl(liveProperties.getPushKey(), streamName, txTime1))
                .toString();

        LiveAddressVO liveAddress = new LiveAddressVO();
        liveAddress.setPushRtmpUrl(pushRtmpUrl);
        liveAddress.setPullRtmpUrl(pullRtmpUrl);
        liveAddress.setPullFlvUrl(pullFlvUrl);
        liveAddress.setPullHlsUrl(pullHlsUrl);
        liveAddress.setPullWebrtcUrl(pullWebrtcUrl);
        liveAddress.setPushWebrtcUrl(pushWebrtcUrl);
        return liveAddress;
    }

    public String[] getTrtcStreamUrl(String streamName) {
        //trtc://cloud.tencent.com/push/streamid?sdkappid=1400188888&userId=A&usersig=xxxxx
        String pushTrtcUrl = new StringBuilder()
                .append("trtc://")
                .append(liveProperties.getTrtcDomain())
                .append("/push/")
                .append(streamName)
                .append("?sdkappid=")
                .append(liveProperties.getImSDKAppID())
                .append("&userId=")
                .append(streamName)
                .append("&usersig=")
                .append(LiveUtils.genUsersig(streamName, liveProperties.getImSDKAppID(), liveProperties.getImSecretKey()))
                .toString();

        String pullTrtcUrl = new StringBuilder()
                .append("trtc://")
                .append(liveProperties.getTrtcDomain())
                .append("/play/")
                .append(streamName)
                .append("?sdkappid=")
                .append(liveProperties.getImSDKAppID())
                .append("&userId=")
                .append(streamName)
                .append("&usersig=")
                .append(LiveUtils.genUsersig(streamName, liveProperties.getImSDKAppID(), liveProperties.getImSecretKey()))
                .toString();

        return new String[]{pushTrtcUrl, pullTrtcUrl};

    }

    /**
     * 批量创建、导入im账号
     * {
     * "UserID":"test",
     * "Nick":"test",
     * "FaceUrl":"http://www.qq.com"
     * }
     *
     * @return
     */

    public TencentApiResponse accountImport(String userId, String nick, String faceUrl) {
        String requestUrl = buildImRequestUrl(API_AccountImport);
        JSONObject requestBody = new JSONObject();
        requestBody.set("UserID", userId);
        requestBody.set("Nick", nick);
        requestBody.set("FaceUrl", faceUrl);
        return postForObject(requestUrl, requestBody);
    }

    /**
     * 查询账号在线状态
     * {
     * "IsNeedDetail": 1,
     * "To_Account": ["id1", "id2", "id4"]
     * }
     *
     * @param
     * @return
     */
    public String queryOnlineStatus() {
        String requestUrl = buildImRequestUrl(API_QueryOnlineStatus);
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("IsNeedDetail", 1);
        jsonObject.set("To_Account", new String[]{"568", "569", "570", "571", "572", "573"});
        return restTemplate.postForObject(requestUrl, jsonObject.toString(), String.class);
    }


    /**
     * {
     * "CheckItem":
     * [
     * {
     * "UserID":"UserID_1"
     * },
     * {
     * "UserID":"UserID_2"
     * }
     * ]
     * }
     *
     * @return
     */
    public String accountCheck(String userId) {
        String requestUrl = buildImRequestUrl(API_AccountCheck);
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        jsonArray.set(new JSONObject().set("UserID", userId));
        jsonObject.set("CheckItem", jsonArray);
        return restTemplate.postForObject(requestUrl, jsonObject.toString(), String.class);
    }

    /**
     * 获取app中的所有群组
     * {
     * "Limit": 1000,
     * "Next": 0,
     * "GroupType" : "Public" // 拉取哪种群组形态，不填为拉取所有
     * }
     *
     * @return
     */
    public String getAllGroupList() {
        String requestUrl = buildImRequestUrl(API_GetAppidGroupList);
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("Limit", 10000);
        jsonObject.set("Next", 0);
        jsonObject.set("GroupType", "AVChatRoom");
        return restTemplate.postForObject(requestUrl, jsonObject.toString(), String.class);
    }

    /**
     * 创建群组
     *
     * @param groupName {
     *                  "Owner_Account": "leckie", // 群主的 UserId（选填）
     *                  "Type": "Public", // 群组类型：Private/Public/ChatRoom/AVChatRoom/Community
     *                  "Name": "TestGroup", // 群名称（必填）
     *                  "GroupId": "MyFirstGroup", // 用户自定义群组 ID（选填）
     *                  "Introduction": "This is group Introduction", // 群简介（选填）
     *                  "Notification": "This is group Notification", // 群公告（选填）
     *                  "FaceUrl": "http://this.is.face.url", // 群头像 URL（选填）
     *                  "MaxMemberCount": 500, // 最大群成员数量（选填）
     *                  "ApplyJoinOption": "FreeAccess",  // 申请加群处理方式（选填）
     *                  "InviteJoinOption": "FreeAccess"//邀请加群处理方式(选填)
     *                  }
     * @return
     */
    public TencentApiResponse createGroup(String groupName) {
        String requestUrl = buildImRequestUrl(API_CreateGroup);
        JSONObject requestBody = new JSONObject();
        requestBody.set("Type", "AVChatRoom");
        requestBody.set("Name", groupName);
        requestBody.set("GroupId", groupName);//自定义群组id
        requestBody.set("Introduction", groupName);
        requestBody.set("Notification", groupName);
        return postForObject(requestUrl, requestBody);
    }


    private String buildImRequestUrl(String api) {
        return LiveUtils.buildImRequestUrl(liveProperties.getImDomain(), api, "administrator", liveProperties.getImSDKAppID(), liveProperties.getImSecretKey());
    }

    public TencentApiResponse postForObject(String url, Object request) throws LiveException {
        TencentApiResponse apiResponse = new TencentApiResponse();
        ResponseEntity<String> entity = restTemplate.postForEntity(url, request.toString(), String.class);
        if (entity.getStatusCode() == HttpStatus.OK) {
            JSONObject jsonObject = new JSONObject(entity.getBody());
            int errorCode = jsonObject.getInt("ErrorCode");
            //String actionStatus = jsonObject.getStr("ActionStatus");
            String errorInfo = jsonObject.getStr("ErrorInfo");
            apiResponse.setCode(errorCode);
            switch (errorCode) {
                case 0:
                case 10021:
                    apiResponse.setData(entity.getBody());
                    break;
                default:
                    apiResponse.setData(errorInfo);
            }
        } else {
            apiResponse.setCode(500);
            apiResponse.setData("Error: " + entity.getStatusCode());
        }

        return apiResponse;
    }
}
